package com.ls.io.rpc.transport;

import com.alibaba.fastjson.JSON;
import com.ls.io.rpc.protobuf.RpcContent;
import com.ls.io.rpc.protobuf.RpcHeader;
import com.ls.io.rpc.protobuf.RpcPackage;
import com.ls.io.rpc.utils.SeriUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.List;

public class RpcMessageDecoder extends ByteToMessageDecoder {

//    @Override
//    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
//        ByteBuf in = (ByteBuf)msg;
//
//        // 如果数据不够长的话，就 return 掉再等一等
//        if (in.readableBytes() <= 20) {
//            return;
//        }
//        int bufferIndex = 0;
//        while (true) {
//            // 记录下索引，后面会用到
//            bufferIndex = in.readerIndex();
//            in.markReaderIndex();
//            // 如果读到包头就可以break了
//            if (in.readInt() == 111) {
//                break;
//            }
//            // 读不到包头的话还原一下标记，然后丢掉一个字节
//            in.resetReaderIndex();
//            in.readByte();
//            if (in.readableBytes() <= 20) {
//                return;
//            }
//        }
//
//        // 刚才   read 了一个int，是包头
//        // 现在再 read 一个 int ，就是长度了
//        long requestId = in.readLong();
//        long length = in.readLong();
//        // 这个时候可能包的长度还没有到齐，我们要再判断一下
//        if (in.readableBytes() < length) {
//            // 没到齐的话就重置一下标记，然后等到齐了再说
//            in.readerIndex(bufferIndex);
//            return ;
//        }
//
//        byte[] data = new byte[(int)length];
//        in.readBytes(data);
//
//        RpcContent content = SeriUtils.unSeriable(data, RpcContent.class);
//
//        RpcHeader header = new RpcHeader();
//        header.setFlag(111);
//        header.setRequestId(requestId);
//        header.setLength(length);
//
//        RpcPackage pck = new RpcPackage(header, content);
//        out.add(pck);
//    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
        ByteBuf buf = (ByteBuf)msg;

        while(buf.readableBytes() > 20){
            int flag = buf.getInt(buf.readerIndex());
            long requestId = buf.getLong(buf.readerIndex() + 4);
            long length = buf.getLong(buf.readerIndex() + 12);

            RpcHeader header = new RpcHeader();
            header.setFlag(flag);
            header.setRequestId(requestId);
            header.setLength(length);

            if(buf.readableBytes() >= length + 20){
                buf.readBytes(20);

                byte[] bytes = new byte[(int)length];
                buf.readBytes(bytes, 0, (int)length);

                String log = "receive header: %s , content: %s";
                System.out.println(String.format(log, JSON.toJSONString(header), new String(bytes, "utf-8")));
                try{
                    RpcContent content = SeriUtils.unSeriable(bytes, RpcContent.class);

                    RpcPackage rpcPackage = new RpcPackage(header, content);
                    out.add(rpcPackage);
                }catch (Exception e){
//                    System.err.println("requestId :" + header.getRequestId() + ", body: " + new String(bytes, "utf-8"));
                    e.printStackTrace();
                    break;
                }

            }
            else{
                break;
            }
        }
    }
}
